﻿using System;
using System.Collections.Generic;
using System.Text;

namespace FlashPay.DAO.Impl
{
    using FlashPay.DAO.Interface;
    using FlashPay.EF;
    using FlashPay.EF.Models;
    using FlashPay.Entity;
    using FlashPay.Entity.Enum;
    using FlashPay.Entity.Parameter;
    using FlashPay.Entity.Response.DepositMatchRule;
    using Microsoft.EntityFrameworkCore;
    using System.Linq;
    using System.Linq.Expressions;

    /// <summary>
    /// 收款匹配规则数据接口实现
    /// </summary>
    public class DepositMatchRuleDaoImpl : DepositMatchRuleDao
    {
        #region 注入
        /// <summary>
        /// EF上下文
        /// </summary>
        private FlashPayContext _context { set; get; }

        /// <summary>
        /// 注入
        /// </summary>
        /// <param name="context"></param>
        public DepositMatchRuleDaoImpl(FlashPayContext context)
        {
            _context = context;
        }

        public void Dispose()
        {
            if (_context != null)
            {
                _context.Dispose();
            }
        }
        #endregion

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id">编号</param>
        public DepositMatchRule Get(int id)
        {
            return _context.DepositMatchRule.Where(x => x.Id == id).FirstOrDefault();
        }

        /// <summary>
        /// 根据companyId、bankcode查询匹配规则
        /// </summary>
        /// <param name="companyId"></param>
        /// <returns></returns>
        public DepositMatchRule GetRuleByCompanyId(int companyId, string bankcode)
        {
            var t = _context.DepositMatchRule.Where(x =>
            (x.MatchBankCode.Contains(bankcode) || string.IsNullOrEmpty(x.MatchBankCode)) && x.CompanyId == companyId
            ).OrderByDescending(x => x.MatchBankCode).ToList();

            DepositMatchRule newMatchRule = new DepositMatchRule();
            for (int i = 0; i < t.Count; i++)
            {
                if (string.IsNullOrEmpty(t[i].MatchBankCode))
                {
                    newMatchRule = t[i];
                    break;
                }
                string[] ss = t[i].MatchBankCode.Split(",");
                for (int j = 0; j < ss.Length; j++)
                {
                    if (ss[j] == bankcode)
                    {
                        newMatchRule = t[i];
                        break;
                    }
                }
            }
            return newMatchRule;
        }

        /// <summary>
        /// 根据companyId、bankcode查询匹配规则
        /// </summary>
        /// <param name="companyId"></param>
        /// <returns></returns>
        public DepositMatchRule GetRuleByCompanyId(DepositMatchRule model)
        {
            // 获取该公司所设定的存款匹配规则
            // 按照银行卡降序排列（设定长度最多的优先）
            var depositMatchRules = _context.DepositMatchRule
                .Where(e => e.CompanyId == model.CompanyId)
                .OrderByDescending(o => o.MatchBankCode)
                .ToList();

            // 检查该公司是否有设定存款匹配规则
            if (depositMatchRules.Count == 0)
            {
                // 没有设定匹配规则，因此不做匹配。
                return null;
            }

            // 从该公司所有的匹配规则列表中，根据收款卡的银行代码找出专属的匹配规则。（因为公司会设置多组匹配逻辑，因此有优先顺序。）
            // 根据文档，优先判断「交易类型 TransType」：反向排序，优先取得有设置交易类型的规则（长度较长的会出现在前面）。
            // 然后才是指定银行：一样进行反向排序，取得有指定银行代码的匹配规则（长度较长的会出现在前面）。
            // 备注：用户的匹配规则设定中，MatchBankCode 与 MatchTransType 有可能是空值（代表套用到全部）或者当有指定数值时则进行比对。
            var rule = depositMatchRules.Where(e =>
                    (string.IsNullOrEmpty(e.MatchBankCode) || !string.IsNullOrEmpty(e.MatchBankCode) && e.MatchBankCode.Split(',').ToList().Contains(model.MatchBankCode)) 
                    &&
                    (string.IsNullOrEmpty(e.MatchTranstype) || !string.IsNullOrEmpty(e.MatchTranstype) && e.MatchTranstype.Split(',').ToList().Contains(model.MatchTranstype.ToString())))
                    .ToList()
                    .OrderByDescending(o => o.MatchTranstype)
                    .ThenByDescending(o => o.MatchBankCode);
            if (rule!=null && rule.Any())
                return rule.FirstOrDefault();
            else
                return null;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Add(DepositMatchRule model, FlashPayContext flashPayContext = null)
        {
            var _flashPayContext = (flashPayContext ?? _context);
            _flashPayContext.DepositMatchRule.Add(model);
            //调用数据上下文的保存方法，将对象存数数据库
            var resultId = _flashPayContext.SaveChanges();

            return model.Id;
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="CardMerchant">修改对象</param>
        /// <returns></returns>
        public bool Update(DepositMatchRule model, FlashPayContext flashPayContext = null)
        {
            var _flashPayContext = (flashPayContext ?? _context);

            _flashPayContext.Entry<DepositMatchRule>(model);
            _flashPayContext.SaveChanges();
            return true;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">系统编号</param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            var model = _context.DepositMatchRule.Find(id);
            if (model != null)
            {
                _context.DepositMatchRule.Remove(model);
                if (_context.SaveChanges() > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public List<DepositMatchRule> GetList(DepositMatchRuleQuery query)
        {
            //多条件查询
            var where = PredicateBuilder.True<DepositMatchRule>();

            if (query.NotEqualId.HasValue)
            {
                where = where.And(c => c.Id != query.NotEqualId.Value);
            }

            if (query.CompanyId.HasValue)
            {
                where = where.And(c => c.CompanyId == query.CompanyId.Value);
            }

            if (query.CompanyIds != null && query.CompanyIds.Any())
            {
                where = where.And(c => query.CompanyIds.Contains(c.CompanyId));
            }

            var list = _context.DepositMatchRule.Where(where.Compile()).ToList();

            return list;
        }

        public void GetThisOneCompanyMatchRule()
        {

        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <returns>PagedList<Permission></returns>
        public PagedList<DepositMatchRuleResponse> GetPager(DepositMatchRuleQuery query)
        {
            var q = from dmr in _context.DepositMatchRule
                    join
                    c in _context.Company on dmr.CompanyId equals c.CompanyId
                    join
                    u in _context.UserInfo on dmr.CreateId equals u.UId
                    select new DepositMatchRuleResponse
                    {
                        Id=dmr.Id,
                        CompanyId=dmr.CompanyId,
                        CompanyName=c.CompanyName,
                        CompanyNameEn=c.CompanyNameEn,
                        MatchMinusMinute = dmr.MatchMinusMinute,
                        MatchMinute=dmr.MatchMinute,
                        MatchBankCode=dmr.MatchBankCode,
                        MatchTranstype=dmr.MatchTranstype,
                        MatchPushRule = dmr.MatchPushRule,
                        MatchRule=dmr.MatchRule,
                        MatchRemark=dmr.MatchRemark,
                        CreateId=dmr.CreateId,
                        CreateDate=dmr.CreateDate
                    };

            //CompanyId
            if (query.CompanyIds != null && query.CompanyIds.Any())
            {
                q = q.Where(c => query.CompanyIds.Contains(c.CompanyId));
            }

            //var list = q.Skip((query.CurrentPageIndex.Value - 1) * query.PageSize.Value).OrderByDescending(p => p.CreateDate).Take(query.PageSize.Value).ToList();
            int currentPage = query.CurrentPageIndex.Value;
            int pageSize = query.PageSize.Value;
            var list = q.OrderByDescending(r => r.CreateDate).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();

            var total = q.Count();

            return new PagedList<DepositMatchRuleResponse>
            {
                TData = list,
                CurrentPageIndex = currentPage,
                TotalCount = total,
                Success = true
            };
        }

    }
}
